﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;

namespace AWSS3ToAzureBlob
{
    public class Program
    {
        [ExcludeFromCodeCoverage]
        static void Main(string[] args)
        {
            //Just for debugging purposes
            //string[] debugArgs = new string[14];
            //args[0] = "-azkey";
            //args[1] = "<Azure Storage Key>";
            //args[2] = "-azaccount";
            //args[3] = "<Azure Storage Account Name>";
            //args[4] = "-azcontainer";
            //args[5] = "<Azure Storage Container Name>";
            //args[6] = "-awskeyid";
            //args[7] = "<AWS S3 Key ID>";
            //args[8] = "-awskey";
            //args[9] = "<AWS S3 Key>";
            //args[10] = "-awsbucket";
            //args[11] = "<AWS S3 Bucket Name>";
            //args[12] = "-awsexpiry";
            //args[13] = "<AWS S3 Pre Signed Url timeout>";

            //MainWithFacades(debugArgs,
            //    new FileMigrator(),
            //    new AWSS3Facade(),
            //    new AzureStorageBlobFacade());

            MainWithFacades(args,
                new FileMigrator(),
                new AWSS3Facade(),
                new AzureStorageBlobFacade());
        }

        private static void AddConsoleTraceListener()
        {
            ConsoleTraceListener listener = new ConsoleTraceListener(true);
            Trace.Listeners.Add(listener);
        }

        public static void MainWithFacades(string[] args,
            IFileMigrator fileMigrator,
            IAWSS3Facade awsS3,
            IAzureStorageBlobFacade azureStorageBlob)
        {
            string awsS3Bucket;
            string awsAccessKeyId;
            string awsSecretKey;
            int awsExpiryMinutes;
            string azureStorageAccount;
            string azureStorageKey;
            string azureStorageContainer;

            AddConsoleTraceListener();

            if (ValidateArgs(args,
                out awsS3Bucket,
                out awsAccessKeyId,
                out awsSecretKey,
                out awsExpiryMinutes,
                out azureStorageAccount,
                out azureStorageKey,
                out azureStorageContainer))
            {
                try
                {
                    fileMigrator.Initialize(awsS3Bucket,
                        awsAccessKeyId,
                        awsSecretKey,
                        awsExpiryMinutes,
                        azureStorageAccount,
                        azureStorageKey,
                        azureStorageContainer,
                        awsS3,
                        azureStorageBlob);

                    fileMigrator.MigrateFiles();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }

        private static bool ValidateArgs(string[] args, 
            out string awsS3Bucket, 
            out string awsAccessKeyId, 
            out string awsSecretKey, 
            out int awsExpiryMinutes, 
            out string azureStorageAccount, 
            out string azureStorageKey, 
            out string azureStorageContainer)
        {
            awsS3Bucket = null;
            awsAccessKeyId = null;
            awsSecretKey = null;
            awsExpiryMinutes = -1;
            azureStorageAccount = null;
            azureStorageKey = null;
            azureStorageContainer = null;

            if (IsEmptyArgs(args))
            {
                DisplayParameterErrorMessage();
                return false;
            }

            if (IsHelp(args))
            {
                DisplayHelp();
                return false;
            }

            if (args.Length != 14)
            {
                DisplayParameterErrorMessage();
                return false;
            }
            else
            {
                for (int i = 0; i < args.Length; i = i +2)
                {
                    switch (args[i].ToLower())
                    {
                        case "/awskeyid":
                        case "-awskeyid":
                            if (awsAccessKeyId != null)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }

                            awsAccessKeyId = args[i + 1];                            
                            break;
                        case "/awskey":
                        case "-awskey":
                            if (awsSecretKey != null)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }

                            awsSecretKey = args[i + 1];
                            break;
                        case "/awsbucket":
                        case "-awsbucket":
                            if (awsS3Bucket != null)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }
                            
                            awsS3Bucket = args[i + 1];
                            break;
                        case "/awsexpiry":
                        case "-awsexpiry":
                            if (awsExpiryMinutes != -1)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }

                            awsExpiryMinutes = Convert.ToInt32(args[i + 1]);
                            break;
                        case "/azaccount":
                        case "-azaccount":
                            if (azureStorageAccount != null)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }

                            azureStorageAccount = args[i + 1];
                            break;
                        case "/azkey":
                        case "-azkey":
                            if (azureStorageKey != null)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }

                            azureStorageKey = args[i + 1];
                            break;
                        case "/azcontainer":
                        case "-azcontainer":
                            if (azureStorageContainer != null)
                            {
                                DisplayParameterErrorMessage();
                                return false;
                            }

                            azureStorageContainer = args[i + 1];
                            break;
                        default:
                            DisplayParameterErrorMessage();
                            return false;
                    }
                }
            }

            return true;
        }

        private static void DisplayParameterErrorMessage()
        {
            Console.WriteLine(Messages.InvalidParameters);
        }

        private static bool IsEmptyArgs(string[] args)
        {
            return args == null || args.Length == 0;
        }

        private static bool IsHelp(string[] args)
        {
            bool returnValue = false;

            if (args.Length == 1)
            {
                switch (args[0].ToLower())
                {
                    case "/h":
                    case "-h":
                        returnValue = true;
                        break;
                }
            }

            return returnValue;
        }

        private static void DisplayHelp()
        {
            Console.WriteLine(Messages.HelpMessage);
        }
    }
}